webhookdb 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/data/messages/layouts/blank.email.liquid +10 -0
- data/data/messages/layouts/minimal.email.liquid +28 -0
- data/data/messages/layouts/standard.email.liquid +28 -0
- data/data/messages/partials/button.liquid +15 -0
- data/data/messages/partials/environment_banner.liquid +9 -0
- data/data/messages/partials/footer.liquid +22 -0
- data/data/messages/partials/greeting.liquid +3 -0
- data/data/messages/partials/logo_header.liquid +18 -0
- data/data/messages/partials/signoff.liquid +1 -0
- data/data/messages/styles/v1.liquid +346 -0
- data/data/messages/templates/errors/icalendar_fetch.email.liquid +29 -0
- data/data/messages/templates/invite.email.liquid +15 -0
- data/data/messages/templates/new_customer.email.liquid +24 -0
- data/data/messages/templates/org_database_migration_finished.email.liquid +7 -0
- data/data/messages/templates/org_database_migration_started.email.liquid +9 -0
- data/data/messages/templates/specs/_field_partial.liquid +1 -0
- data/data/messages/templates/specs/basic.email.liquid +2 -0
- data/data/messages/templates/specs/basic.fake.liquid +1 -0
- data/data/messages/templates/specs/with_field.email.liquid +2 -0
- data/data/messages/templates/specs/with_field.fake.liquid +1 -0
- data/data/messages/templates/specs/with_include.email.liquid +2 -0
- data/data/messages/templates/specs/with_partial.email.liquid +1 -0
- data/data/messages/templates/verification.email.liquid +14 -0
- data/data/messages/templates/verification.sms.liquid +1 -0
- data/data/messages/web/install-customer-login.liquid +48 -0
- data/data/messages/web/install-error.liquid +17 -0
- data/data/messages/web/install-success.liquid +35 -0
- data/data/messages/web/install.liquid +20 -0
- data/data/messages/web/partials/footer.liquid +4 -0
- data/data/messages/web/partials/form_error.liquid +1 -0
- data/data/messages/web/partials/header.liquid +3 -0
- data/data/messages/web/styles.liquid +134 -0
- data/data/windows_tz.txt +461 -0
- data/db/migrations/001_testing_pixies.rb +13 -0
- data/db/migrations/002_initial.rb +132 -0
- data/db/migrations/003_ux_overhaul.rb +20 -0
- data/db/migrations/004_incremental_backfill.rb +9 -0
- data/db/migrations/005_log_webhooks.rb +24 -0
- data/db/migrations/006_generalize_roles.rb +29 -0
- data/db/migrations/007_org_dns.rb +12 -0
- data/db/migrations/008_webhook_subscriptions.rb +19 -0
- data/db/migrations/009_nonunique_stripe_subscription_customer.rb +16 -0
- data/db/migrations/010_drop_integration_soft_delete.rb +14 -0
- data/db/migrations/011_webhook_subscriptions_created_at.rb +10 -0
- data/db/migrations/012_webhook_subscriptions_created_by.rb +9 -0
- data/db/migrations/013_default_org_membership.rb +30 -0
- data/db/migrations/014_webhook_subscription_deliveries.rb +26 -0
- data/db/migrations/015_dependent_integrations.rb +9 -0
- data/db/migrations/016_encrypted_columns.rb +9 -0
- data/db/migrations/017_skip_verification.rb +9 -0
- data/db/migrations/018_sync_targets.rb +25 -0
- data/db/migrations/019_org_schema.rb +9 -0
- data/db/migrations/020_org_database_migrations.rb +25 -0
- data/db/migrations/021_no_default_org_schema.rb +14 -0
- data/db/migrations/022_database_document.rb +15 -0
- data/db/migrations/023_sync_target_schema.rb +9 -0
- data/db/migrations/024_org_semaphore_jobs.rb +9 -0
- data/db/migrations/025_integration_backfill_cursor.rb +9 -0
- data/db/migrations/026_undo_integration_backfill_cursor.rb +9 -0
- data/db/migrations/027_sync_target_http_sync.rb +12 -0
- data/db/migrations/028_logged_webhook_path.rb +24 -0
- data/db/migrations/029_encrypt_columns.rb +97 -0
- data/db/migrations/030_org_sync_target_timeout.rb +9 -0
- data/db/migrations/031_org_max_query_rows.rb +9 -0
- data/db/migrations/032_remove_db_defaults.rb +12 -0
- data/db/migrations/033_backfill_jobs.rb +26 -0
- data/db/migrations/034_backfill_job_criteria.rb +9 -0
- data/db/migrations/035_synchronous_backfill.rb +9 -0
- data/db/migrations/036_oauth.rb +26 -0
- data/db/migrations/037_oauth_used.rb +9 -0
- data/lib/amigo/durable_job.rb +416 -0
- data/lib/pry/clipboard.rb +111 -0
- data/lib/sequel/advisory_lock.rb +65 -0
- data/lib/webhookdb/admin.rb +4 -0
- data/lib/webhookdb/admin_api/auth.rb +36 -0
- data/lib/webhookdb/admin_api/customers.rb +63 -0
- data/lib/webhookdb/admin_api/database_documents.rb +20 -0
- data/lib/webhookdb/admin_api/entities.rb +66 -0
- data/lib/webhookdb/admin_api/message_deliveries.rb +61 -0
- data/lib/webhookdb/admin_api/roles.rb +15 -0
- data/lib/webhookdb/admin_api.rb +34 -0
- data/lib/webhookdb/aggregate_result.rb +63 -0
- data/lib/webhookdb/api/auth.rb +122 -0
- data/lib/webhookdb/api/connstr_auth.rb +36 -0
- data/lib/webhookdb/api/db.rb +188 -0
- data/lib/webhookdb/api/demo.rb +14 -0
- data/lib/webhookdb/api/entities.rb +198 -0
- data/lib/webhookdb/api/helpers.rb +253 -0
- data/lib/webhookdb/api/install.rb +296 -0
- data/lib/webhookdb/api/me.rb +53 -0
- data/lib/webhookdb/api/organizations.rb +254 -0
- data/lib/webhookdb/api/replay.rb +64 -0
- data/lib/webhookdb/api/service_integrations.rb +402 -0
- data/lib/webhookdb/api/services.rb +27 -0
- data/lib/webhookdb/api/stripe.rb +22 -0
- data/lib/webhookdb/api/subscriptions.rb +67 -0
- data/lib/webhookdb/api/sync_targets.rb +232 -0
- data/lib/webhookdb/api/system.rb +37 -0
- data/lib/webhookdb/api/webhook_subscriptions.rb +96 -0
- data/lib/webhookdb/api.rb +92 -0
- data/lib/webhookdb/apps.rb +93 -0
- data/lib/webhookdb/async/audit_logger.rb +38 -0
- data/lib/webhookdb/async/autoscaler.rb +84 -0
- data/lib/webhookdb/async/job.rb +18 -0
- data/lib/webhookdb/async/job_logger.rb +45 -0
- data/lib/webhookdb/async/scheduled_job.rb +18 -0
- data/lib/webhookdb/async.rb +142 -0
- data/lib/webhookdb/aws.rb +98 -0
- data/lib/webhookdb/backfill_job.rb +107 -0
- data/lib/webhookdb/backfiller.rb +107 -0
- data/lib/webhookdb/cloudflare.rb +39 -0
- data/lib/webhookdb/connection_cache.rb +177 -0
- data/lib/webhookdb/console.rb +71 -0
- data/lib/webhookdb/convertkit.rb +14 -0
- data/lib/webhookdb/crypto.rb +66 -0
- data/lib/webhookdb/customer/reset_code.rb +94 -0
- data/lib/webhookdb/customer.rb +347 -0
- data/lib/webhookdb/database_document.rb +72 -0
- data/lib/webhookdb/db_adapter/column_types.rb +37 -0
- data/lib/webhookdb/db_adapter/default_sql.rb +187 -0
- data/lib/webhookdb/db_adapter/pg.rb +96 -0
- data/lib/webhookdb/db_adapter/snowflake.rb +137 -0
- data/lib/webhookdb/db_adapter.rb +208 -0
- data/lib/webhookdb/dbutil.rb +92 -0
- data/lib/webhookdb/demo_mode.rb +100 -0
- data/lib/webhookdb/developer_alert.rb +51 -0
- data/lib/webhookdb/email_octopus.rb +21 -0
- data/lib/webhookdb/enumerable.rb +18 -0
- data/lib/webhookdb/fixtures/backfill_jobs.rb +72 -0
- data/lib/webhookdb/fixtures/customers.rb +65 -0
- data/lib/webhookdb/fixtures/database_documents.rb +27 -0
- data/lib/webhookdb/fixtures/faker.rb +41 -0
- data/lib/webhookdb/fixtures/logged_webhooks.rb +56 -0
- data/lib/webhookdb/fixtures/message_deliveries.rb +59 -0
- data/lib/webhookdb/fixtures/oauth_sessions.rb +24 -0
- data/lib/webhookdb/fixtures/organization_database_migrations.rb +37 -0
- data/lib/webhookdb/fixtures/organization_memberships.rb +54 -0
- data/lib/webhookdb/fixtures/organizations.rb +32 -0
- data/lib/webhookdb/fixtures/reset_codes.rb +23 -0
- data/lib/webhookdb/fixtures/service_integrations.rb +42 -0
- data/lib/webhookdb/fixtures/subscriptions.rb +33 -0
- data/lib/webhookdb/fixtures/sync_targets.rb +32 -0
- data/lib/webhookdb/fixtures/webhook_subscriptions.rb +35 -0
- data/lib/webhookdb/fixtures.rb +15 -0
- data/lib/webhookdb/formatting.rb +56 -0
- data/lib/webhookdb/front.rb +49 -0
- data/lib/webhookdb/github.rb +22 -0
- data/lib/webhookdb/google_calendar.rb +29 -0
- data/lib/webhookdb/heroku.rb +21 -0
- data/lib/webhookdb/http.rb +114 -0
- data/lib/webhookdb/icalendar.rb +17 -0
- data/lib/webhookdb/id.rb +17 -0
- data/lib/webhookdb/idempotency.rb +90 -0
- data/lib/webhookdb/increase.rb +42 -0
- data/lib/webhookdb/intercom.rb +23 -0
- data/lib/webhookdb/jobs/amigo_test_jobs.rb +118 -0
- data/lib/webhookdb/jobs/backfill.rb +32 -0
- data/lib/webhookdb/jobs/create_mirror_table.rb +18 -0
- data/lib/webhookdb/jobs/create_stripe_customer.rb +17 -0
- data/lib/webhookdb/jobs/customer_created_notify_internal.rb +22 -0
- data/lib/webhookdb/jobs/demo_mode_sync_data.rb +19 -0
- data/lib/webhookdb/jobs/deprecated_jobs.rb +19 -0
- data/lib/webhookdb/jobs/developer_alert_handle.rb +14 -0
- data/lib/webhookdb/jobs/durable_job_recheck_poller.rb +17 -0
- data/lib/webhookdb/jobs/emailer.rb +15 -0
- data/lib/webhookdb/jobs/icalendar_enqueue_syncs.rb +25 -0
- data/lib/webhookdb/jobs/icalendar_sync.rb +23 -0
- data/lib/webhookdb/jobs/logged_webhook_replay.rb +17 -0
- data/lib/webhookdb/jobs/logged_webhook_resilient_replay.rb +15 -0
- data/lib/webhookdb/jobs/message_dispatched.rb +16 -0
- data/lib/webhookdb/jobs/organization_database_migration_notify_finished.rb +21 -0
- data/lib/webhookdb/jobs/organization_database_migration_notify_started.rb +21 -0
- data/lib/webhookdb/jobs/organization_database_migration_run.rb +24 -0
- data/lib/webhookdb/jobs/prepare_database_connections.rb +22 -0
- data/lib/webhookdb/jobs/process_webhook.rb +47 -0
- data/lib/webhookdb/jobs/renew_watch_channel.rb +24 -0
- data/lib/webhookdb/jobs/replication_migration.rb +24 -0
- data/lib/webhookdb/jobs/reset_code_create_dispatch.rb +23 -0
- data/lib/webhookdb/jobs/scheduled_backfills.rb +77 -0
- data/lib/webhookdb/jobs/send_invite.rb +15 -0
- data/lib/webhookdb/jobs/send_test_webhook.rb +25 -0
- data/lib/webhookdb/jobs/send_webhook.rb +20 -0
- data/lib/webhookdb/jobs/sync_target_enqueue_scheduled.rb +16 -0
- data/lib/webhookdb/jobs/sync_target_run_sync.rb +38 -0
- data/lib/webhookdb/jobs/trim_logged_webhooks.rb +15 -0
- data/lib/webhookdb/jobs/webhook_resource_notify_integrations.rb +30 -0
- data/lib/webhookdb/jobs/webhook_subscription_delivery_attempt.rb +29 -0
- data/lib/webhookdb/jobs.rb +4 -0
- data/lib/webhookdb/json.rb +113 -0
- data/lib/webhookdb/liquid/expose.rb +27 -0
- data/lib/webhookdb/liquid/filters.rb +16 -0
- data/lib/webhookdb/liquid/liquification.rb +26 -0
- data/lib/webhookdb/liquid/partial.rb +12 -0
- data/lib/webhookdb/logged_webhook/resilient.rb +95 -0
- data/lib/webhookdb/logged_webhook.rb +194 -0
- data/lib/webhookdb/message/body.rb +25 -0
- data/lib/webhookdb/message/delivery.rb +127 -0
- data/lib/webhookdb/message/email_transport.rb +133 -0
- data/lib/webhookdb/message/fake_transport.rb +54 -0
- data/lib/webhookdb/message/liquid_drops.rb +29 -0
- data/lib/webhookdb/message/template.rb +89 -0
- data/lib/webhookdb/message/transport.rb +43 -0
- data/lib/webhookdb/message.rb +150 -0
- data/lib/webhookdb/messages/error_icalendar_fetch.rb +42 -0
- data/lib/webhookdb/messages/invite.rb +23 -0
- data/lib/webhookdb/messages/new_customer.rb +14 -0
- data/lib/webhookdb/messages/org_database_migration_finished.rb +23 -0
- data/lib/webhookdb/messages/org_database_migration_started.rb +24 -0
- data/lib/webhookdb/messages/specs.rb +57 -0
- data/lib/webhookdb/messages/verification.rb +23 -0
- data/lib/webhookdb/method_utilities.rb +82 -0
- data/lib/webhookdb/microsoft_calendar.rb +36 -0
- data/lib/webhookdb/nextpax.rb +14 -0
- data/lib/webhookdb/oauth/front.rb +58 -0
- data/lib/webhookdb/oauth/intercom.rb +58 -0
- data/lib/webhookdb/oauth/session.rb +24 -0
- data/lib/webhookdb/oauth.rb +80 -0
- data/lib/webhookdb/organization/alerting.rb +35 -0
- data/lib/webhookdb/organization/database_migration.rb +151 -0
- data/lib/webhookdb/organization/db_builder.rb +429 -0
- data/lib/webhookdb/organization.rb +506 -0
- data/lib/webhookdb/organization_membership.rb +58 -0
- data/lib/webhookdb/phone_number.rb +38 -0
- data/lib/webhookdb/plaid.rb +23 -0
- data/lib/webhookdb/platform.rb +27 -0
- data/lib/webhookdb/plivo.rb +52 -0
- data/lib/webhookdb/postgres/maintenance.rb +166 -0
- data/lib/webhookdb/postgres/model.rb +82 -0
- data/lib/webhookdb/postgres/model_utilities.rb +382 -0
- data/lib/webhookdb/postgres/testing_pixie.rb +16 -0
- data/lib/webhookdb/postgres/validations.rb +46 -0
- data/lib/webhookdb/postgres.rb +176 -0
- data/lib/webhookdb/postmark.rb +20 -0
- data/lib/webhookdb/redis.rb +35 -0
- data/lib/webhookdb/replicator/atom_single_feed_v1.rb +116 -0
- data/lib/webhookdb/replicator/aws_pricing_v1.rb +488 -0
- data/lib/webhookdb/replicator/base.rb +1185 -0
- data/lib/webhookdb/replicator/column.rb +482 -0
- data/lib/webhookdb/replicator/convertkit_broadcast_v1.rb +69 -0
- data/lib/webhookdb/replicator/convertkit_subscriber_v1.rb +200 -0
- data/lib/webhookdb/replicator/convertkit_tag_v1.rb +66 -0
- data/lib/webhookdb/replicator/convertkit_v1_mixin.rb +65 -0
- data/lib/webhookdb/replicator/docgen.rb +167 -0
- data/lib/webhookdb/replicator/email_octopus_campaign_v1.rb +84 -0
- data/lib/webhookdb/replicator/email_octopus_contact_v1.rb +159 -0
- data/lib/webhookdb/replicator/email_octopus_event_v1.rb +244 -0
- data/lib/webhookdb/replicator/email_octopus_list_v1.rb +101 -0
- data/lib/webhookdb/replicator/fake.rb +453 -0
- data/lib/webhookdb/replicator/front_conversation_v1.rb +45 -0
- data/lib/webhookdb/replicator/front_marketplace_root_v1.rb +55 -0
- data/lib/webhookdb/replicator/front_message_v1.rb +45 -0
- data/lib/webhookdb/replicator/front_v1_mixin.rb +22 -0
- data/lib/webhookdb/replicator/github_issue_comment_v1.rb +58 -0
- data/lib/webhookdb/replicator/github_issue_v1.rb +83 -0
- data/lib/webhookdb/replicator/github_pull_v1.rb +84 -0
- data/lib/webhookdb/replicator/github_release_v1.rb +47 -0
- data/lib/webhookdb/replicator/github_repo_v1_mixin.rb +250 -0
- data/lib/webhookdb/replicator/github_repository_event_v1.rb +45 -0
- data/lib/webhookdb/replicator/icalendar_calendar_v1.rb +465 -0
- data/lib/webhookdb/replicator/icalendar_event_v1.rb +334 -0
- data/lib/webhookdb/replicator/increase_account_number_v1.rb +77 -0
- data/lib/webhookdb/replicator/increase_account_transfer_v1.rb +61 -0
- data/lib/webhookdb/replicator/increase_account_v1.rb +63 -0
- data/lib/webhookdb/replicator/increase_ach_transfer_v1.rb +78 -0
- data/lib/webhookdb/replicator/increase_check_transfer_v1.rb +64 -0
- data/lib/webhookdb/replicator/increase_limit_v1.rb +78 -0
- data/lib/webhookdb/replicator/increase_transaction_v1.rb +74 -0
- data/lib/webhookdb/replicator/increase_v1_mixin.rb +121 -0
- data/lib/webhookdb/replicator/increase_wire_transfer_v1.rb +61 -0
- data/lib/webhookdb/replicator/intercom_contact_v1.rb +36 -0
- data/lib/webhookdb/replicator/intercom_conversation_v1.rb +38 -0
- data/lib/webhookdb/replicator/intercom_marketplace_root_v1.rb +69 -0
- data/lib/webhookdb/replicator/intercom_v1_mixin.rb +105 -0
- data/lib/webhookdb/replicator/oauth_refresh_access_token_mixin.rb +65 -0
- data/lib/webhookdb/replicator/plivo_sms_inbound_v1.rb +102 -0
- data/lib/webhookdb/replicator/postmark_inbound_message_v1.rb +94 -0
- data/lib/webhookdb/replicator/postmark_outbound_message_event_v1.rb +107 -0
- data/lib/webhookdb/replicator/schema_modification.rb +42 -0
- data/lib/webhookdb/replicator/shopify_customer_v1.rb +58 -0
- data/lib/webhookdb/replicator/shopify_order_v1.rb +64 -0
- data/lib/webhookdb/replicator/shopify_v1_mixin.rb +161 -0
- data/lib/webhookdb/replicator/signalwire_message_v1.rb +169 -0
- data/lib/webhookdb/replicator/sponsy_customer_v1.rb +54 -0
- data/lib/webhookdb/replicator/sponsy_placement_v1.rb +34 -0
- data/lib/webhookdb/replicator/sponsy_publication_v1.rb +125 -0
- data/lib/webhookdb/replicator/sponsy_slot_v1.rb +41 -0
- data/lib/webhookdb/replicator/sponsy_status_v1.rb +35 -0
- data/lib/webhookdb/replicator/sponsy_v1_mixin.rb +165 -0
- data/lib/webhookdb/replicator/state_machine_step.rb +69 -0
- data/lib/webhookdb/replicator/stripe_charge_v1.rb +77 -0
- data/lib/webhookdb/replicator/stripe_coupon_v1.rb +62 -0
- data/lib/webhookdb/replicator/stripe_customer_v1.rb +60 -0
- data/lib/webhookdb/replicator/stripe_dispute_v1.rb +77 -0
- data/lib/webhookdb/replicator/stripe_invoice_item_v1.rb +82 -0
- data/lib/webhookdb/replicator/stripe_invoice_v1.rb +116 -0
- data/lib/webhookdb/replicator/stripe_payout_v1.rb +67 -0
- data/lib/webhookdb/replicator/stripe_price_v1.rb +60 -0
- data/lib/webhookdb/replicator/stripe_product_v1.rb +60 -0
- data/lib/webhookdb/replicator/stripe_refund_v1.rb +101 -0
- data/lib/webhookdb/replicator/stripe_subscription_item_v1.rb +56 -0
- data/lib/webhookdb/replicator/stripe_subscription_v1.rb +75 -0
- data/lib/webhookdb/replicator/stripe_v1_mixin.rb +116 -0
- data/lib/webhookdb/replicator/transistor_episode_stats_v1.rb +141 -0
- data/lib/webhookdb/replicator/transistor_episode_v1.rb +169 -0
- data/lib/webhookdb/replicator/transistor_show_v1.rb +68 -0
- data/lib/webhookdb/replicator/transistor_v1_mixin.rb +65 -0
- data/lib/webhookdb/replicator/twilio_sms_v1.rb +156 -0
- data/lib/webhookdb/replicator/webhook_request.rb +5 -0
- data/lib/webhookdb/replicator/webhookdb_customer_v1.rb +74 -0
- data/lib/webhookdb/replicator.rb +224 -0
- data/lib/webhookdb/role.rb +42 -0
- data/lib/webhookdb/sentry.rb +35 -0
- data/lib/webhookdb/service/auth.rb +138 -0
- data/lib/webhookdb/service/collection.rb +91 -0
- data/lib/webhookdb/service/entities.rb +97 -0
- data/lib/webhookdb/service/helpers.rb +270 -0
- data/lib/webhookdb/service/middleware.rb +124 -0
- data/lib/webhookdb/service/types.rb +30 -0
- data/lib/webhookdb/service/validators.rb +32 -0
- data/lib/webhookdb/service/view_api.rb +63 -0
- data/lib/webhookdb/service.rb +219 -0
- data/lib/webhookdb/service_integration.rb +332 -0
- data/lib/webhookdb/shopify.rb +35 -0
- data/lib/webhookdb/signalwire.rb +13 -0
- data/lib/webhookdb/slack.rb +68 -0
- data/lib/webhookdb/snowflake.rb +90 -0
- data/lib/webhookdb/spec_helpers/async.rb +122 -0
- data/lib/webhookdb/spec_helpers/citest.rb +88 -0
- data/lib/webhookdb/spec_helpers/integration.rb +121 -0
- data/lib/webhookdb/spec_helpers/message.rb +41 -0
- data/lib/webhookdb/spec_helpers/postgres.rb +220 -0
- data/lib/webhookdb/spec_helpers/service.rb +432 -0
- data/lib/webhookdb/spec_helpers/shared_examples_for_columns.rb +56 -0
- data/lib/webhookdb/spec_helpers/shared_examples_for_replicators.rb +915 -0
- data/lib/webhookdb/spec_helpers/whdb.rb +139 -0
- data/lib/webhookdb/spec_helpers.rb +63 -0
- data/lib/webhookdb/sponsy.rb +14 -0
- data/lib/webhookdb/stripe.rb +37 -0
- data/lib/webhookdb/subscription.rb +203 -0
- data/lib/webhookdb/sync_target.rb +491 -0
- data/lib/webhookdb/tasks/admin.rb +49 -0
- data/lib/webhookdb/tasks/annotate.rb +36 -0
- data/lib/webhookdb/tasks/db.rb +82 -0
- data/lib/webhookdb/tasks/docs.rb +42 -0
- data/lib/webhookdb/tasks/fixture.rb +35 -0
- data/lib/webhookdb/tasks/message.rb +50 -0
- data/lib/webhookdb/tasks/regress.rb +87 -0
- data/lib/webhookdb/tasks/release.rb +27 -0
- data/lib/webhookdb/tasks/sidekiq.rb +23 -0
- data/lib/webhookdb/tasks/specs.rb +64 -0
- data/lib/webhookdb/theranest.rb +15 -0
- data/lib/webhookdb/transistor.rb +13 -0
- data/lib/webhookdb/twilio.rb +13 -0
- data/lib/webhookdb/typed_struct.rb +44 -0
- data/lib/webhookdb/version.rb +5 -0
- data/lib/webhookdb/webhook_response.rb +50 -0
- data/lib/webhookdb/webhook_subscription/delivery.rb +82 -0
- data/lib/webhookdb/webhook_subscription.rb +226 -0
- data/lib/webhookdb/windows_tz.rb +32 -0
- data/lib/webhookdb/xml.rb +92 -0
- data/lib/webhookdb.rb +224 -0
- data/lib/webterm/apps.rb +45 -0
- metadata +1129 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "grape"
|
|
4
|
+
require "oj"
|
|
5
|
+
|
|
6
|
+
require "webhookdb/api"
|
|
7
|
+
require "webhookdb/formatting"
|
|
8
|
+
require "webhookdb/replicator"
|
|
9
|
+
require "webhookdb/async/audit_logger"
|
|
10
|
+
require "webhookdb/jobs/process_webhook"
|
|
11
|
+
|
|
12
|
+
class Webhookdb::API::ServiceIntegrations < Webhookdb::API::V1
|
|
13
|
+
# These URLs are not used by the CLI-
|
|
14
|
+
# they are the url that customers should point their webhooks to.
|
|
15
|
+
# We can't check org permissions on this endpoint
|
|
16
|
+
# because external services (so no auth) will be posting webhooks here.
|
|
17
|
+
# Depend on webhook verification to ensure the request is valid.
|
|
18
|
+
resource :service_integrations do
|
|
19
|
+
route [:post, :put, :delete, :patch], "/:opaque_id*" do
|
|
20
|
+
opaque_id = params[:opaque_id]
|
|
21
|
+
handle_webhook_request(opaque_id) do
|
|
22
|
+
Webhookdb::ServiceIntegration[opaque_id:] or merror!(400, "No integration with that id")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
resource :organizations do
|
|
28
|
+
route_param :org_identifier, type: String do
|
|
29
|
+
resource :service_integrations do
|
|
30
|
+
desc "Return all integrations associated with the organization."
|
|
31
|
+
get do
|
|
32
|
+
integrations = lookup_org!.service_integrations
|
|
33
|
+
message = ""
|
|
34
|
+
if integrations.empty?
|
|
35
|
+
message = "This organization doesn't have any integrations set up yet.\n" \
|
|
36
|
+
"Use `webhookdb services list` and `webhookdb integrations create` to set one up."
|
|
37
|
+
end
|
|
38
|
+
present_collection integrations, with: Webhookdb::API::ServiceIntegrationEntity, message:
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
resource :create do
|
|
42
|
+
helpers do
|
|
43
|
+
def create_integration(org, name)
|
|
44
|
+
available_services_list = org.available_replicator_names.sort.join("\n\t")
|
|
45
|
+
|
|
46
|
+
service_name_invalid = Webhookdb::Replicator.registered(name).nil?
|
|
47
|
+
if service_name_invalid
|
|
48
|
+
message = %(WebhookDB doesn't support a service called '#{name}.'
|
|
49
|
+
These are all the services currently supported by WebhookDB:
|
|
50
|
+
|
|
51
|
+
\t#{available_services_list}
|
|
52
|
+
|
|
53
|
+
Run `webhookdb services list` to see available services, and try again with the new name.)
|
|
54
|
+
merror!(400, message, code: "invalid_service", alert: true)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# If org does not have access to the given service
|
|
58
|
+
unless org.available_replicator_names.include?(name)
|
|
59
|
+
step = Webhookdb::Replicator::StateMachineStep.new
|
|
60
|
+
step.needs_input = false
|
|
61
|
+
step.output =
|
|
62
|
+
%(
|
|
63
|
+
Your organization does not have permission to view the service called '#{name}.' These are all the services
|
|
64
|
+
you currently have access to:
|
|
65
|
+
|
|
66
|
+
\t#{available_services_list}
|
|
67
|
+
|
|
68
|
+
You can run `webhookdb services list` at any time to see the list of services available to your organization.
|
|
69
|
+
If the list does not look correct, you can contact support at #{Webhookdb.support_email}.)
|
|
70
|
+
step.complete = true
|
|
71
|
+
return step
|
|
72
|
+
end
|
|
73
|
+
sint = Webhookdb::ServiceIntegration.create_disambiguated(name, organization: org)
|
|
74
|
+
replicator = sint.replicator
|
|
75
|
+
# We always want to enqueue the backfill job if it is possible to do so, even if
|
|
76
|
+
# we are not returning the backfill step in our response to this create request
|
|
77
|
+
if replicator.descriptor.supports_backfill?
|
|
78
|
+
backfill_step, _job = replicator.calculate_and_backfill_state_machine(incremental: true)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Prefer creating using webhooks, not backfilling, but fall back to backfilling.
|
|
82
|
+
return replicator.calculate_webhook_state_machine if replicator.descriptor.supports_webhooks?
|
|
83
|
+
return backfill_step
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def verify_unique_integration(org)
|
|
87
|
+
existing = Webhookdb::ServiceIntegration.where(
|
|
88
|
+
organization: org,
|
|
89
|
+
service_name: params[:service_name],
|
|
90
|
+
).first
|
|
91
|
+
return if existing.nil?
|
|
92
|
+
return if params.key?(:guard_confirm)
|
|
93
|
+
Webhookdb::API::Helpers.prompt_for_required_param!(
|
|
94
|
+
request,
|
|
95
|
+
:guard_confirm,
|
|
96
|
+
"WARNING: #{org.name} already has an integration for service #{params[:service_name]}.\n" \
|
|
97
|
+
"Press Enter to create another, or Ctrl+C to quit.\n" \
|
|
98
|
+
"Modify the existing integration using `webhookdb integrations #{existing.opaque_id} setup`",
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
desc "Create service integration on a given organization"
|
|
103
|
+
params do
|
|
104
|
+
optional :service_name, type: String,
|
|
105
|
+
prompt: "Enter the name of the service to create an integration for.\n" \
|
|
106
|
+
"Run 'webhookdb services list' to see available services:"
|
|
107
|
+
optional :guard_confirm
|
|
108
|
+
end
|
|
109
|
+
post do
|
|
110
|
+
customer = current_customer
|
|
111
|
+
org = lookup_org!
|
|
112
|
+
merror!(402, "You have reached the maximum number of free integrations", alert: true) unless
|
|
113
|
+
org.can_add_new_integration?
|
|
114
|
+
ensure_admin!
|
|
115
|
+
verify_unique_integration(org)
|
|
116
|
+
step = nil
|
|
117
|
+
customer.db.transaction do
|
|
118
|
+
step = create_integration(org, params[:service_name])
|
|
119
|
+
# No reason to create the integration when this happens.
|
|
120
|
+
# We may want to expand the situations we roll back,
|
|
121
|
+
# but we start by being targeted.
|
|
122
|
+
raise Sequel::Rollback if step.error_code == "no_candidate_dependency"
|
|
123
|
+
end
|
|
124
|
+
status 200
|
|
125
|
+
present step, with: Webhookdb::API::StateMachineEntity
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
route_param :sint_identifier, type: String do
|
|
130
|
+
helpers do
|
|
131
|
+
def ensure_plan_supports!(org=nil)
|
|
132
|
+
org ||= lookup_org!
|
|
133
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
134
|
+
return if sint.plan_supports_integration?
|
|
135
|
+
err_msg = "This integration is no longer supported. " \
|
|
136
|
+
"Run `webhookdb subscription edit` to manage your subscription."
|
|
137
|
+
merror!(402, err_msg, alert: true)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def ensure_can_be_modified!(sint, c)
|
|
141
|
+
permission_error!("Sorry, you cannot modify this integration.") unless sint.can_be_modified_by?(c)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
post :setup do
|
|
146
|
+
ensure_plan_supports!
|
|
147
|
+
c = current_customer
|
|
148
|
+
org = lookup_org!
|
|
149
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
150
|
+
svc = Webhookdb::Replicator.create(sint)
|
|
151
|
+
merror!(403, "Sorry, you cannot modify this integration.") unless sint.can_be_modified_by?(c)
|
|
152
|
+
state_machine = svc.calculate_preferred_create_state_machine
|
|
153
|
+
status 200
|
|
154
|
+
present state_machine, with: Webhookdb::API::StateMachineEntity
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
post :reset do
|
|
158
|
+
ensure_plan_supports!
|
|
159
|
+
c = current_customer
|
|
160
|
+
org = lookup_org!
|
|
161
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
162
|
+
svc = Webhookdb::Replicator.create(sint)
|
|
163
|
+
merror!(403, "Sorry, you cannot modify this integration.") unless sint.can_be_modified_by?(c)
|
|
164
|
+
svc.clear_webhook_information
|
|
165
|
+
state_machine = svc.calculate_preferred_create_state_machine
|
|
166
|
+
status 200
|
|
167
|
+
present state_machine, with: Webhookdb::API::StateMachineEntity
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
post :upsert do
|
|
171
|
+
current_customer
|
|
172
|
+
org = lookup_org!
|
|
173
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
174
|
+
svc = Webhookdb::Replicator.create(sint)
|
|
175
|
+
body = env["api.request.body"]
|
|
176
|
+
begin
|
|
177
|
+
svc.upsert_webhook_body(body)
|
|
178
|
+
rescue KeyError, TypeError => e
|
|
179
|
+
self.logger.error "immediate_upsert", error: e
|
|
180
|
+
err_msg = "Sorry! Looks like something has gone wrong. " \
|
|
181
|
+
"Check your schema or contact support at #{Webhookdb.support_email}."
|
|
182
|
+
merror!(400, err_msg)
|
|
183
|
+
end
|
|
184
|
+
status 200
|
|
185
|
+
present({}, with: Webhookdb::API::BaseEntity, message: "You have upserted into #{sint.table_name}.")
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
desc "Returns information about the integration."
|
|
189
|
+
params do
|
|
190
|
+
optional :field, type: String, values: Webhookdb::ServiceIntegration::INTEGRATION_INFO_FIELDS
|
|
191
|
+
end
|
|
192
|
+
post :info do
|
|
193
|
+
ensure_plan_supports!
|
|
194
|
+
org = lookup_org!
|
|
195
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
196
|
+
data = {
|
|
197
|
+
id: sint.opaque_id,
|
|
198
|
+
service: sint.service_name,
|
|
199
|
+
table: sint.table_name,
|
|
200
|
+
url: sint.replicator.webhook_endpoint,
|
|
201
|
+
webhook_secret: sint.webhook_secret,
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
field_name = params[:field]
|
|
205
|
+
blocks = Webhookdb::Formatting.blocks
|
|
206
|
+
if field_name.present?
|
|
207
|
+
blocks.line(data.fetch(field_name.to_sym))
|
|
208
|
+
else
|
|
209
|
+
rows = data.map do |k, v|
|
|
210
|
+
[k.to_s.capitalize, v]
|
|
211
|
+
end
|
|
212
|
+
blocks.table(["Field", "Value"], rows)
|
|
213
|
+
end
|
|
214
|
+
r = {blocks: blocks.as_json}
|
|
215
|
+
status 200
|
|
216
|
+
present r
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
resource :backfill do
|
|
220
|
+
helpers do
|
|
221
|
+
def lookup_backfillable_replicator(customer:, allow_connstr_auth: false)
|
|
222
|
+
org = lookup_org!(allow_connstr_auth:)
|
|
223
|
+
ensure_plan_supports!(org)
|
|
224
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
225
|
+
ensure_can_be_modified!(sint, customer) if customer
|
|
226
|
+
return sint.replicator
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def ensure_backfill_supported!(rep)
|
|
230
|
+
return if rep.descriptor.supports_backfill?
|
|
231
|
+
msg = rep.backfill_not_supported_message
|
|
232
|
+
merror!(409, msg)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
params do
|
|
237
|
+
optional :incremental, type: Boolean
|
|
238
|
+
end
|
|
239
|
+
post do
|
|
240
|
+
rep = lookup_backfillable_replicator(customer: current_customer)
|
|
241
|
+
ensure_backfill_supported!(rep)
|
|
242
|
+
state_machine, _ = rep.calculate_and_backfill_state_machine(incremental: params.fetch(:incremental, true))
|
|
243
|
+
status 200
|
|
244
|
+
present state_machine, with: Webhookdb::API::StateMachineEntity
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
post :reset do
|
|
248
|
+
repl = lookup_backfillable_replicator(customer: current_customer)
|
|
249
|
+
ensure_backfill_supported!(repl)
|
|
250
|
+
state_machine = repl.service_integration.db.transaction do
|
|
251
|
+
repl.clear_backfill_information
|
|
252
|
+
step, _ = repl.calculate_and_backfill_state_machine(incremental: true)
|
|
253
|
+
step
|
|
254
|
+
end
|
|
255
|
+
status 200
|
|
256
|
+
present state_machine, with: Webhookdb::API::StateMachineEntity
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
resource :job do
|
|
260
|
+
params do
|
|
261
|
+
optional :incremental, type: Boolean, default: true
|
|
262
|
+
optional :criteria, type: JSON
|
|
263
|
+
optional :recursive, type: Boolean, default: true
|
|
264
|
+
optional :synchronous, type: Boolean
|
|
265
|
+
end
|
|
266
|
+
post do
|
|
267
|
+
rep = lookup_backfillable_replicator(customer: nil, allow_connstr_auth: true)
|
|
268
|
+
ensure_backfill_supported!(rep)
|
|
269
|
+
sint = rep.service_integration
|
|
270
|
+
incremental = params.fetch(:incremental)
|
|
271
|
+
recursive = params.fetch(:recursive)
|
|
272
|
+
if (synchronous = params[:synchronous] || false)
|
|
273
|
+
invalid!("Recursive backfills cannot be synchronous") if recursive
|
|
274
|
+
invalid!("Only incremental backfills can be synchronous") unless incremental
|
|
275
|
+
unless sint.organization.priority_backfill
|
|
276
|
+
merror!(402,
|
|
277
|
+
"Organization does not support sychronous backfills",
|
|
278
|
+
code: "priority_backfill_not_enabled",)
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
_, job = rep.calculate_and_backfill_state_machine(
|
|
282
|
+
incremental:,
|
|
283
|
+
recursive:,
|
|
284
|
+
criteria: params[:criteria] || nil,
|
|
285
|
+
enqueue: !synchronous,
|
|
286
|
+
)
|
|
287
|
+
if job.nil?
|
|
288
|
+
msg = "Sorry, this integration is not set up to backfill. " \
|
|
289
|
+
"Run `webhookdb backfill #{sint.opaque_id}` to finish setup."
|
|
290
|
+
merror!(409, msg, code: "backfill_not_set_up")
|
|
291
|
+
end
|
|
292
|
+
sint.replicator.backfill(job) if synchronous
|
|
293
|
+
status 200
|
|
294
|
+
present job, with: Webhookdb::API::BackfillJobEntity
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
route_param :job_id, type: String do
|
|
298
|
+
get do
|
|
299
|
+
org = lookup_org!(allow_connstr_auth: true)
|
|
300
|
+
job = Webhookdb::BackfillJob[service_integration: org.service_integrations_dataset,
|
|
301
|
+
opaque_id: params[:job_id]]
|
|
302
|
+
forbidden! if job.nil?
|
|
303
|
+
present job, with: Webhookdb::API::BackfillJobEntity
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
resource :transition do
|
|
310
|
+
route_param :field do
|
|
311
|
+
params do
|
|
312
|
+
requires :value
|
|
313
|
+
end
|
|
314
|
+
post do
|
|
315
|
+
ensure_plan_supports!
|
|
316
|
+
c = current_customer
|
|
317
|
+
org = lookup_org!
|
|
318
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
319
|
+
ensure_can_be_modified!(sint, c)
|
|
320
|
+
state_machine = sint.replicator.process_state_change(params[:field], params[:value])
|
|
321
|
+
status 200
|
|
322
|
+
present state_machine, with: Webhookdb::API::StateMachineEntity
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
desc "Gets stats about webhooks for this service integration."
|
|
328
|
+
get :stats do
|
|
329
|
+
org = lookup_org!
|
|
330
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
331
|
+
stats = sint.stats
|
|
332
|
+
status 200
|
|
333
|
+
present stats.as_json
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
params do
|
|
337
|
+
optional :confirm, type: String
|
|
338
|
+
end
|
|
339
|
+
post :delete do
|
|
340
|
+
ensure_plan_supports!
|
|
341
|
+
ensure_admin!
|
|
342
|
+
org = lookup_org!
|
|
343
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
344
|
+
dependents_lines = sint.recursive_dependents.map(&:table_name).join("\n")
|
|
345
|
+
if sint.table_name != params[:confirm]&.strip
|
|
346
|
+
output = if sint.dependents.empty?
|
|
347
|
+
"Please confirm your deletion by entering the integration's table name '" \
|
|
348
|
+
"#{sint.table_name}'. The table and all data for this integration will also be removed."
|
|
349
|
+
else
|
|
350
|
+
%(This integration has dependents and therefore cannot be deleted on its own.
|
|
351
|
+
If you choose to go forward with the deletion, WebhookDB will recursively delete all dependents.
|
|
352
|
+
For reference, this includes the following integrations:
|
|
353
|
+
|
|
354
|
+
#{dependents_lines}
|
|
355
|
+
|
|
356
|
+
Please confirm your deletion by entering the integration's table name '#{sint.table_name}'.
|
|
357
|
+
The tables and all data for this integration and its dependents will also be removed:)
|
|
358
|
+
end
|
|
359
|
+
Webhookdb::API::Helpers.prompt_for_required_param!(
|
|
360
|
+
request,
|
|
361
|
+
:confirm,
|
|
362
|
+
"Confirm table name '#{sint.table_name}':",
|
|
363
|
+
output:,
|
|
364
|
+
)
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
sint.destroy_self_and_all_dependents
|
|
368
|
+
status 200
|
|
369
|
+
|
|
370
|
+
if sint.dependents.empty?
|
|
371
|
+
confirmation_msg = "Great! We've deleted all secrets for #{sint.service_name}. " \
|
|
372
|
+
"The table #{sint.table_name} containing its data has been dropped."
|
|
373
|
+
else
|
|
374
|
+
confirmation_msg = "Great! We've deleted all secrets for #{sint.service_name} and its dependents. " \
|
|
375
|
+
"The following tables have been dropped: \n\n #{sint.table_name} \n #{dependents_lines}"
|
|
376
|
+
end
|
|
377
|
+
present sint, with: Webhookdb::API::ServiceIntegrationEntity, message: confirmation_msg
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
params do
|
|
381
|
+
optional :new_name,
|
|
382
|
+
type: String,
|
|
383
|
+
db_identifier: true,
|
|
384
|
+
prompt: "Enter the new name of the table. " + Webhookdb::DBAdapter::INVALID_IDENTIFIER_MESSAGE
|
|
385
|
+
end
|
|
386
|
+
post :rename_table do
|
|
387
|
+
org = lookup_org!
|
|
388
|
+
sint = lookup_service_integration!(org, params[:sint_identifier])
|
|
389
|
+
ensure_admin!
|
|
390
|
+
old_name = sint.table_name
|
|
391
|
+
sint.db.transaction do
|
|
392
|
+
sint.rename_table(to: params[:new_name])
|
|
393
|
+
message = "The table for #{sint.service_name} has been renamed from #{old_name} to #{sint.table_name}."
|
|
394
|
+
status 200
|
|
395
|
+
present sint, with: Webhookdb::API::ServiceIntegrationEntity, message:
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "grape"
|
|
4
|
+
|
|
5
|
+
require "webhookdb/api"
|
|
6
|
+
require "webhookdb/replicator"
|
|
7
|
+
|
|
8
|
+
class Webhookdb::API::Services < Webhookdb::API::V1
|
|
9
|
+
resource :services do
|
|
10
|
+
route_param :service_name, type: String do
|
|
11
|
+
get :fixtures do
|
|
12
|
+
begin
|
|
13
|
+
descr = Webhookdb::Replicator.registered!(params[:service_name])
|
|
14
|
+
rescue Webhookdb::Replicator::Invalid
|
|
15
|
+
merror!(403, "No service with that name exists.")
|
|
16
|
+
end
|
|
17
|
+
sint = Webhookdb::ServiceIntegration.new(
|
|
18
|
+
service_name: params[:service_name],
|
|
19
|
+
opaque_id: "svi_fixture",
|
|
20
|
+
table_name: params[:service_name] + "_fixture",
|
|
21
|
+
)
|
|
22
|
+
sch = descr.ctor.call(sint).create_table_modification.to_s
|
|
23
|
+
present({schema_sql: sch})
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "webhookdb/stripe"
|
|
4
|
+
require "webhookdb/api"
|
|
5
|
+
|
|
6
|
+
class Webhookdb::API::Stripe < Webhookdb::API::V1
|
|
7
|
+
resource :stripe do
|
|
8
|
+
resource :webhook do
|
|
9
|
+
post do
|
|
10
|
+
whresp = Webhookdb::Stripe.webhook_response(request, Webhookdb::Stripe.webhook_secret)
|
|
11
|
+
s_status, s_headers, s_body = whresp.to_rack
|
|
12
|
+
if s_status < 400 && request.params["data"]["object"]["object"] == "subscription"
|
|
13
|
+
Webhookdb::Subscription.create_or_update_from_webhook(request.params)
|
|
14
|
+
end
|
|
15
|
+
env["warden"].custom_failure!
|
|
16
|
+
s_headers.each { |k, v| header k, v }
|
|
17
|
+
body s_body
|
|
18
|
+
status s_status
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "grape"
|
|
4
|
+
|
|
5
|
+
require "webhookdb/api"
|
|
6
|
+
require "webhookdb/admin_api"
|
|
7
|
+
|
|
8
|
+
class Webhookdb::API::Subscriptions < Webhookdb::API::V1
|
|
9
|
+
resource :organizations do
|
|
10
|
+
route_param :org_identifier, type: String do
|
|
11
|
+
resource :subscriptions do
|
|
12
|
+
desc "Provides the user with subscription information for the organization"
|
|
13
|
+
get do
|
|
14
|
+
org = lookup_org!
|
|
15
|
+
status = Webhookdb::Subscription.status_for_org(org)
|
|
16
|
+
status 200
|
|
17
|
+
present status.as_json
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc "Authenticates stripe user and returns stripe checkout session or billing portal url"
|
|
21
|
+
params do
|
|
22
|
+
optional :plan, type: String
|
|
23
|
+
optional :guard_confirm
|
|
24
|
+
end
|
|
25
|
+
post :open_portal do
|
|
26
|
+
org = lookup_org!
|
|
27
|
+
merror!(409, "This organization is not registered with Stripe.", alert: true) if org.stripe_customer_id.blank?
|
|
28
|
+
subscription = Webhookdb::Subscription[stripe_customer_id: org.stripe_customer_id]
|
|
29
|
+
if subscription
|
|
30
|
+
if params[:plan] && !params.key?(:guard_confirm)
|
|
31
|
+
Webhookdb::API::Helpers.prompt_for_required_param!(
|
|
32
|
+
request,
|
|
33
|
+
:guard_confirm,
|
|
34
|
+
"WARNING: You already have a subscription, but have specified a plan.\n" \
|
|
35
|
+
"You will be brought to your subscription so you can modify or cancel it.\n" \
|
|
36
|
+
"Press Enter to continue:",
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
session_url = org.get_stripe_billing_portal_url
|
|
40
|
+
else
|
|
41
|
+
plans = Webhookdb::Subscription.list_plans
|
|
42
|
+
real_plan = plans.find { |p| p.key == params[:plan] }
|
|
43
|
+
unless real_plan
|
|
44
|
+
Webhookdb::API::Helpers.prompt_for_required_param!(
|
|
45
|
+
request,
|
|
46
|
+
:plan,
|
|
47
|
+
"Available plans: #{plans.map(&:key).join(', ')}\nEnter the plan you want to subscribe to:",
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
session_url = org.get_stripe_checkout_url(real_plan.stripe_price_id)
|
|
51
|
+
end
|
|
52
|
+
data = {url: session_url}
|
|
53
|
+
status 200
|
|
54
|
+
present data
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
desc "Returns information about subscription plans"
|
|
58
|
+
get :plans do
|
|
59
|
+
plans = Webhookdb::Subscription.list_plans
|
|
60
|
+
message = "Use `webhookdb subscription edit` to set up or modify your subscription."
|
|
61
|
+
status 200
|
|
62
|
+
present_collection plans, with: Webhookdb::API::SubscriptionPlanEntity, message:
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|