Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/actions/create-or-update-secret/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: 'Create or Update Secret'
description: 'Creates or updates a secret in the repository'

inputs:
secret_name:
description: 'Secret name'
required: true
secret_value:
description: 'Secret value'
required: true
sync_secret_app_id:
description: 'Sync secret app id'
required: true
sync_secret_app_private_key:
description: 'Sync secret app private key'
required: true
runs:
using: 'composite'
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ inputs.sync_secret_app_id }}
private-key: ${{ inputs.sync_secret_app_private_key }}
- name: Set secret
shell: bash
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
gh secret set ${{ inputs.secret_name }} --body "${{ inputs.secret_value }}"
39 changes: 0 additions & 39 deletions .github/actions/refresh-instagram-access-tokens/action.yml

This file was deleted.

53 changes: 53 additions & 0 deletions .github/actions/refresh-instagram-tokens/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: 'Refresh Instagram Access Tokens'
description: 'Refreshes Instagram access token, updates the integrations secrets and update the token GitHub secrets'

inputs:
token_cloud_ops_account:
description: 'Cloud Ops account token'
required: true
cloud_ops_workspace_id:
description: 'Cloud Ops workspace id'
required: true
api_url:
description: 'API URL'
required: true
current_token:
description: 'Current token'
required: true
secret_name:
description: 'Secret name'
required: true
sync_secret_app_id:
description: 'Create or update secret app id'
required: true
sync_secret_app_private_key:
description: 'Create or update secret app private key'
required: true
runs:
using: 'composite'
steps:
- name: Refresh Access Tokens
id: refresh_tokens
shell: bash
env:
BP_API_URL: ${{ inputs.api_url }}
BP_WORKSPACE_ID: ${{ inputs.cloud_ops_workspace_id }}
BP_TOKEN: ${{ inputs.token_cloud_ops_account }}
run: |
refresh_result=$(pnpm -F 'instagram' exec -- pnpm run --silent refreshTokens --json --refreshToken "${{ inputs.current_token }}")
new_token=$(echo "$refresh_result" | jq -r '.refreshedToken')
if [ -z "$new_token" ]; then
echo "❌ Error: Failed to refresh token" >&2
exit 1
fi

echo "$refresh_result" | jq -r '.message'
echo "✅ Tokens refreshed successfully"
echo "::add-mask::$new_token"
echo "new_token=$new_token" >> "$GITHUB_OUTPUT"
- uses: ./.github/actions/create-or-update-secret
with:
secret_name: ${{ inputs.secret_name }}
secret_value: ${{ steps.refresh_tokens.outputs.new_token }}
sync_secret_app_id: ${{ inputs.sync_secret_app_id }}
sync_secret_app_private_key: ${{ inputs.sync_secret_app_private_key }}
34 changes: 0 additions & 34 deletions .github/scripts/refresh-instagram-access-tokens.sh

This file was deleted.

24 changes: 19 additions & 5 deletions .github/workflows/refresh-instagram-access-tokens-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
schedule:
# Run at 10:00 AM EST (15:00 UTC) on the first Tuesday of every month
- cron: '0 15 1-7 * 2'
workflow_dispatch:

jobs:
refresh-tokens:
Expand All @@ -14,12 +15,25 @@ jobs:
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F instagram'
extra_filters: '-F @botpresshub/instagram'
- name: Refresh Instagram Access Tokens
uses: ./.github/actions/refresh-instagram-access-tokens
uses: ./.github/actions/refresh-instagram-tokens
with:
environment: production
item_name: 'Secrets - Instagram'
field_name: 'Sandbox Access Token - Instagram User - Botpress Sandbox'
token_cloud_ops_account: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
api_url: https://api.botpress.cloud
current_token: ${{ secrets.PRODUCTION_INSTAGRAM_ACCESS_TOKEN }}
secret_name: PRODUCTION_INSTAGRAM_ACCESS_TOKEN
sync_secret_app_id: ${{ vars.SYNC_SECRET_APP_ID }}
sync_secret_app_private_key: ${{ secrets.SYNC_SECRET_APP_PRIVATE_KEY }}
ping-success:
runs-on: depot-ubuntu-22.04-8
needs: [refresh-tokens]
steps:
- run: curl -m 10 --retry 5 ${{ secrets.INSTAGRAM_REFRESH_TOKEN_PING_URL }}
ping-failure:
runs-on: depot-ubuntu-22.04-8
if: ${{ failure() }}
needs: [refresh-tokens]
steps:
- run: curl -m 10 --retry 5 ${{ secrets.INSTAGRAM_REFRESH_TOKEN_PING_URL }}/fail
13 changes: 8 additions & 5 deletions .github/workflows/refresh-instagram-access-tokens-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
schedule:
# Run at 10:00 AM EST (15:00 UTC) on the first Tuesday of every month
- cron: '0 15 1-7 * 2'
workflow_dispatch:

jobs:
refresh-tokens:
Expand All @@ -14,12 +15,14 @@ jobs:
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F instagram'
extra_filters: '-F @botpresshub/instagram'
- name: Refresh Instagram Access Tokens
uses: ./.github/actions/refresh-instagram-access-tokens
uses: ./.github/actions/refresh-instagram-tokens
with:
environment: staging
item_name: 'Secrets - Instagram'
field_name: 'Sandbox Access Token - Instagram User - Botpress Sandbox (Staging)'
token_cloud_ops_account: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.STAGING_CLOUD_OPS_WORKSPACE_ID }}
api_url: https://api.botpress.dev
current_token: ${{ secrets.STAGING_INSTAGRAM_ACCESS_TOKEN }}
secret_name: STAGING_INSTAGRAM_ACCESS_TOKEN
sync_secret_app_id: ${{ vars.SYNC_SECRET_APP_ID }}
sync_secret_app_private_key: ${{ secrets.SYNC_SECRET_APP_PRIVATE_KEY }}
22 changes: 10 additions & 12 deletions integrations/instagram/refreshTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ const argsSchema = z.object({
apiUrl: z.string(),
workspaceId: z.string(),
token: z.string(),
instagramRefreshToken: z.string(),
refreshToken: z.string(),
json: z.boolean(),
useProvidedToken: z.boolean(),
})
type RefreshSecretArgs = {
instagramRefreshToken: string
type RefreshSecretArgs = Pick<z.infer<typeof argsSchema>, 'refreshToken' | 'json'> & {
client: Client
json: boolean
useProvidedToken: boolean
log: (message: string) => void
}
Expand All @@ -25,7 +23,7 @@ const DEFAULT_API_URL = 'https://api.botpress.cloud'
const INSTAGRAM_GRAPH_API_URL = 'https://graph.instagram.com'

async function refreshSandboxAccessToken(args: RefreshSecretArgs) {
const { instagramRefreshToken, client, useProvidedToken, log } = args
const { refreshToken, client, useProvidedToken, log } = args

const { integrations: integrationsList } = await client.listIntegrations({
name: 'instagram',
Expand Down Expand Up @@ -57,14 +55,14 @@ async function refreshSandboxAccessToken(args: RefreshSecretArgs) {
if (useProvidedToken) {
log('Using provided token, skipping refresh on Instagram API')
data = {
access_token: instagramRefreshToken,
access_token: refreshToken,
}
} else {
log('Refreshing access token on Instagram API')
const response = await axios.get(`${INSTAGRAM_GRAPH_API_URL}/refresh_access_token`, {
params: {
grant_type: 'ig_refresh_token',
access_token: instagramRefreshToken,
access_token: refreshToken,
},
})
data = response.data
Expand All @@ -73,7 +71,7 @@ async function refreshSandboxAccessToken(args: RefreshSecretArgs) {
for (const integration of integrations) {
await client.updateIntegration({
id: integration.id,
public: integration.public,
visibility: integration.visibility,
secrets: {
[INTEGRATION_SECRET_SANDBOX_ACCESS_TOKEN]: data.access_token,
},
Expand All @@ -94,15 +92,15 @@ async function main() {
apiUrl: { type: 'string', default: process.env.BP_API_URL || DEFAULT_API_URL },
workspaceId: { type: 'string', default: process.env.BP_WORKSPACE_ID },
token: { type: 'string', default: process.env.BP_TOKEN },
instagramRefreshToken: { type: 'string' },
refreshToken: { type: 'string' },
json: { type: 'boolean', default: false },
useProvidedToken: { type: 'boolean', default: false },
},
})

try {
const args = argsSchema.parse(values)
const { apiUrl, token, workspaceId, instagramRefreshToken, json, useProvidedToken } = args
const { apiUrl, token, workspaceId, refreshToken, json, useProvidedToken } = args
const messages: string[] = []
const log = (message: string) => {
if (!json) {
Expand All @@ -117,14 +115,14 @@ async function main() {

const client = new Client({ apiUrl, token, workspaceId })
const refreshResult = await refreshSandboxAccessToken({
instagramRefreshToken,
refreshToken,
client,
json,
useProvidedToken,
log,
})
const output = json
? JSON.stringify({ message: messages.join('\\n'), messages, ...refreshResult }, null, 2)
? JSON.stringify({ message: messages.join('\n'), messages, ...refreshResult }, null, 2)
: `New token: ${refreshResult.refreshedToken}`
console.info(output)
process.exit(0)
Expand Down
Loading
Loading