Edits history of script submission #22239 for ' Create Task Webhook (apify)'

  • bun
    One script reply has been approved by the moderators
    Ap­pro­ved
    import { createHash } from 'node:crypto';
    import { ApifyClient } from 'apify-client@^2.19.0';
    
    type ApifyApiKey = {
      api_key: string;
    };
    
    type Apify = {
      token: string;
    };
    
    type WebhookEventTypes =
      | 'ACTOR.RUN.SUCCEEDED'
      | 'ACTOR.RUN.FAILED'
      | 'ACTOR.RUN.TIMED_OUT'
      | 'ACTOR.RUN.ABORTED'
    
    type ApifyWebhookConfig = {
      url: string;
      token: string;
    };
    
    export type DynSelect_taskId = string;
    export async function taskId(api_key?: ApifyApiKey, oauth_token?: Apify) {
      if (!api_key?.api_key && !oauth_token?.token) {
        return [{ value: '', label: 'Missing Apify API key or OAuth token' }];
      }
    
      try {
        const client = createClient(api_key, oauth_token);
    
        const data = await client.tasks().list();
        const items = data?.items ?? [];
    
        return items.map((task: any) => ({
          value: task.id,
          label: task.title || task.name || task.id,
        }));
      } catch (error: any) {
        return [
          { value: '', label: `Failed to load tasks: ${error.message || error}` },
        ];
      }
    }
    
    function prettifyEvent(e: string) {
      return e.replace(/^ACTOR\.RUN\./, '');
    }
    
    function generateIdempotencyKey(
      id: string,
      eventTypes: WebhookEventTypes[],
      requestUrl: string
    ): string {
      const sortedEventTypes = [...eventTypes].sort();
      const url = new URL(requestUrl);
      const pathname = url.pathname;
      const hash = createHash('sha256');
      hash.update(`${id}:${sortedEventTypes.join(',')}:${pathname}`);
      return hash.digest('hex');
    }
    
    const createClient = (api_key?: ApifyApiKey, oauth_token?: Apify): ApifyClient => {
      const token = oauth_token?.token ?? api_key?.api_key;
      if (!token) {
        throw new Error('Missing Apify API key or OAuth token');
      }
    
      return new ApifyClient({
        token: token,
        requestInterceptors: [
          (request) => {
            if (!request.headers) {
              request.headers = {};
            }
            request.headers['x-apify-integration-platform'] = 'windmill';
            return request;
          },
        ],
      });
    };
    
    export async function main(
      apifyWebhookConfig: ApifyWebhookConfig,
      taskId: DynSelect_taskId,
      eventTypes: WebhookEventTypes[],
      api_key?: ApifyApiKey,
      oauth_token?: Apify,
    ) {
      if (!taskId) {
        return { error: 'Task ID is required' };
      }
    
      const client = createClient(api_key, oauth_token);
    
      const idempotencyKey = generateIdempotencyKey(
        taskId,
        eventTypes,
        apifyWebhookConfig.url
      );
      const headersTemplate = JSON.stringify({
        Authorization: `Bearer ${apifyWebhookConfig.token}`,
      });
    
      // get task to store name for later webhook deletion
      const task = await client.task(taskId).get();
      const taskName = task && (task.title || task.name);
      const webhookEvents = eventTypes
        .map((event) => prettifyEvent(event))
        .join(', ');
    
      try {
        const response = await client.webhooks().create({
          requestUrl: apifyWebhookConfig.url,
          eventTypes: eventTypes,
          condition: {
            actorTaskId: taskId,
          },
          idempotencyKey,
          headersTemplate,
          shouldInterpolateStrings: true,
          description: `${taskName}: ${webhookEvents}`,
          title: "Windmill integration"
        });
    
        return response;
      } catch (e: any) {
        return { error: `Failed to create a webhook. Reason: ${e.message}` };
      }
    }
    

    Submitted by jakub.drobnik222 172 days ago