CampaignFlow Client
View SourceAn Elixir client library for the Campaign Flow API, built with the Req HTTP client.
⚠️ AI Generated! ⚠️
Full disclosure, this repo was almost completely generated by Claude Code. Use at your own risk.
Features
- OAuth2 client credentials authentication
- Automatic token management and refresh
- Full API coverage for all Campaign Flow endpoints
- Type-safe function signatures with
@spec - Comprehensive error handling
- Support for both production and test environments
- Configurable via application config or runtime options
Installation
Add campaign_flow to your list of dependencies in mix.exs:
def deps do
[
{:campaign_flow, "~> 0.1.0"}
]
endConfiguration
Application Config
Configure the client in your config/config.exs:
config :campaign_flow,
client_id: System.get_env("CAMPAIGNFLOW_CLIENT_ID"),
client_secret: System.get_env("CAMPAIGNFLOW_CLIENT_SECRET")Environment Selection
Use the environment option to select between production and test APIs:
# Production (default) - uses https://app.campaignflow.com.au/api/v2
config :campaign_flow,
environment: :prod,
client_id: "your_client_id",
client_secret: "your_client_secret"
# Test - uses https://test.campaignflow.com.au/api/v2
config :campaign_flow,
environment: :test,
client_id: "your_client_id",
client_secret: "your_client_secret"You can also override with a custom base_url if needed:
config :campaign_flow,
base_url: "https://custom.example.com/api/v2",
client_id: "your_client_id",
client_secret: "your_client_secret"Runtime Config
For production, use config/runtime.exs:
import Config
if config_env() == :prod do
config :campaign_flow,
environment: :prod,
client_id: System.get_env("CAMPAIGNFLOW_CLIENT_ID"),
client_secret: System.get_env("CAMPAIGNFLOW_CLIENT_SECRET")
endEnvironment Variables
Set the following environment variables:
export CAMPAIGNFLOW_CLIENT_ID="your_client_id"
export CAMPAIGNFLOW_CLIENT_SECRET="your_client_secret"
Usage
Creating a Client
# Using application config (environment determined by config)
client = CampaignFlow.Client.new()
# Pass credentials directly (defaults to production)
client = CampaignFlow.Client.new(
client_id: "your_client_id",
client_secret: "your_client_secret"
)
# Specify test environment
client = CampaignFlow.Client.new(
client_id: "your_client_id",
client_secret: "your_client_secret",
environment: :test
)
# Or use the convenience function for test environment
client = CampaignFlow.Client.test(
client_id: "your_client_id",
client_secret: "your_client_secret"
)Campaigns
# List campaigns
{{:ok, campaigns}, client} = CampaignFlow.Client.Campaigns.list(client)
# Get a specific campaign
{{:ok, campaign}, client} = CampaignFlow.Client.Campaigns.get(client, 123)
# Create a new campaign
{{:ok, campaign}, client} = CampaignFlow.Client.Campaigns.create(client, %{
name: "Summer Campaign 2024",
agency_id: 1,
property_id: 2
})
# Update a campaign
{{:ok, campaign}, client} = CampaignFlow.Client.Campaigns.update(client, 123, %{
name: "Updated Campaign Name"
})
# Add a comment to a campaign
{{:ok, response}, client} = CampaignFlow.Client.Campaigns.add_comment(client, 123, %{
comment: "Campaign approved by client"
})
# Set campaign status
{{:ok, response}, client} = CampaignFlow.Client.Campaigns.set_status(client, 123, %{
status: "approved"
})
# Send approved email
{{:ok, response}, client} = CampaignFlow.Client.Campaigns.send_approved_email(client, 123)Campaign Vendors
# List campaign vendors
{{:ok, vendors}, client} = CampaignFlow.Client.Campaigns.list_vendors(client, 123)
# Get a specific vendor
{{:ok, vendor}, client} = CampaignFlow.Client.Campaigns.get_vendor(client, 123, 456)
# Add a vendor to a campaign
{{:ok, vendor}, client} = CampaignFlow.Client.Campaigns.add_vendor(client, 123, %{
vendor_id: 456
})
# Update a campaign vendor
{{:ok, vendor}, client} = CampaignFlow.Client.Campaigns.update_vendor(client, 123, 456, %{
status: "approved"
})
# Remove a vendor from a campaign
{{:ok, response}, client} = CampaignFlow.Client.Campaigns.remove_vendor(client, 123, 456)
# Send campaign to vendor
{{:ok, response}, client} = CampaignFlow.Client.Campaigns.send_campaign_to_vendor(client, 123, 456)
# Verify vendor contact
{{:ok, response}, client} = CampaignFlow.Client.Campaigns.verify_vendor_contact(client, 123, 456)Agencies
# List agencies
{{:ok, agencies}, client} = CampaignFlow.Client.Agencies.list(client)
# Get a specific agency
{{:ok, agency}, client} = CampaignFlow.Client.Agencies.get(client, 123)Invoices
# List invoices
{{:ok, invoices}, client} = CampaignFlow.Client.Invoices.list(client)
# Get a specific invoice
{{:ok, invoice}, client} = CampaignFlow.Client.Invoices.get(client, 123)
# Create an invoice
{{:ok, invoice}, client} = CampaignFlow.Client.Invoices.create(client, %{
campaign_id: 123,
amount: 1000.00
})
# Update an invoice
{{:ok, invoice}, client} = CampaignFlow.Client.Invoices.update(client, 123, %{
amount: 1200.00
})Campaign Budgets
# List campaign budgets
{{:ok, budgets}, client} = CampaignFlow.Client.CampaignBudgets.list(client)
# Get a specific budget
{{:ok, budget}, client} = CampaignFlow.Client.CampaignBudgets.get(client, 123)
# Create a campaign budget
{{:ok, budget}, client} = CampaignFlow.Client.CampaignBudgets.create(client, %{
campaign_id: 123,
amount: 10000.00
})
# Update a campaign budget
{{:ok, budget}, client} = CampaignFlow.Client.CampaignBudgets.update(client, 123, %{
amount: 12000.00
})
# List finance options
{{:ok, options}, client} = CampaignFlow.Client.CampaignBudgets.list_finance_options(client, 123)
# Get a finance quote
{{:ok, quote}, client} = CampaignFlow.Client.CampaignBudgets.get_finance_quote(client, 123, "OPTION_CODE")Finance Applications
# List finance applications
{{:ok, applications}, client} = CampaignFlow.Client.FinanceApplications.list(client)
# Get a specific application
{{:ok, application}, client} = CampaignFlow.Client.FinanceApplications.get(client, 123)
# Set application status
{{:ok, response}, client} = CampaignFlow.Client.FinanceApplications.set_status(client, 123, %{
status: "approved"
})
# Submit an application
{{:ok, response}, client} = CampaignFlow.Client.FinanceApplications.submit(client, 123)Users, Tenants, Properties
# Users
{{:ok, users}, client} = CampaignFlow.Client.Users.list(client)
{{:ok, user}, client} = CampaignFlow.Client.Users.get(client, 123)
# Tenants
{{:ok, tenants}, client} = CampaignFlow.Client.Tenants.list(client)
{{:ok, tenant}, client} = CampaignFlow.Client.Tenants.get(client, 123)
# Properties
{{:ok, properties}, client} = CampaignFlow.Client.Properties.list(client)
{{:ok, property}, client} = CampaignFlow.Client.Properties.get(client, 123)Error Handling
The client returns tuples with {:ok, result} or {:error, reason}:
case CampaignFlow.Client.Campaigns.get(client, 123) do
{{:ok, campaign}, updated_client} ->
# Process campaign
IO.inspect(campaign)
updated_client
{{:error, :not_found}, client} ->
# Handle not found
IO.puts("Campaign not found")
client
{{:error, :unauthorized}, client} ->
# Handle authentication error
IO.puts("Authentication failed")
client
{{:error, {:validation_error, details}}, client} ->
# Handle validation errors
IO.inspect(details)
client
{{:error, reason}, client} ->
# Handle other errors
IO.inspect(reason)
client
endPagination
Most list endpoints support pagination:
# Get page 2 with 50 items per page
{{:ok, campaigns}, client} = CampaignFlow.Client.Campaigns.list(client,
page: 2,
per_page: 50
)Authentication
The client automatically handles OAuth2 authentication using the client credentials flow:
- When you make your first API request, the client automatically obtains an access token
- The token is cached and reused for subsequent requests
- When the token expires, a new one is automatically obtained
You don't need to manually manage authentication - it's handled transparently.
Client State Management
Note that the client struct is updated with each request to maintain the current access token. You should use the updated client returned from each function call:
# Initial client
client = CampaignFlow.Client.new(client_id: "...", client_secret: "...")
# Client is updated after each request
{{:ok, campaigns}, client} = CampaignFlow.Client.Campaigns.list(client)
{{:ok, campaign}, client} = CampaignFlow.Client.Campaigns.get(client, 123)
# Use the updated client for the next request
{{:ok, agencies}, client} = CampaignFlow.Client.Agencies.list(client)Available Resources
The following resource modules are available:
CampaignFlow.Client.Campaigns- Campaign managementCampaignFlow.Client.Agencies- Agency operationsCampaignFlow.Client.Invoices- Invoice managementCampaignFlow.Client.CampaignBudgets- Campaign budget operationsCampaignFlow.Client.FinanceApplications- Finance application managementCampaignFlow.Client.Users- User operationsCampaignFlow.Client.Tenants- Tenant managementCampaignFlow.Client.Properties- Property operationsCampaignFlow.Client.Referrals- Referral managementCampaignFlow.Client.Signatories- Signatory operations
Development
# Get dependencies
mix deps.get
# Run tests
mix test
# Generate documentation
mix docs
# Format code
mix format
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.