Description: 'Create voice to text automation system using SNS, S3, lambda, transcribe'

Parameters:

  AdminSMS:
    Description: Your mobile number to receive text messages, fomat +19876544321
    Type: String

  LanguageCode:
    Type: String
    Description: 'The language code of your audio file i.e en-US https://docs.aws.amazon.com/transcribe/latest/dg/what-is-transcribe.html'

  SourceS3Bucket:
    Type: String
    Description: 'The unique bucket name where audio file from user will be uploaded and accessed'

Resources:
    SnsTopic:
      Type: AWS::SNS::Topic
      Properties:
        DisplayName: !Sub ${AWS::StackName}-Notifications
        Subscription:
          -
            Endpoint: !Ref AdminSMS
            Protocol: SMS
    #S3 bucket to store the recording

    LambdaTranscribe:
      Type: AWS::Lambda::Function
      Properties:
         Handler: index.lambda_handler
         Role:
           Fn::GetAtt:
             - "lambdaRoletoRunTranscribe"
             - "Arn"
         Runtime: python3.7
         Timeout: 500
         Environment:
           Variables:
             SnsTopic: !Ref 'SnsTopic'
             LanguageCode: !Ref 'LanguageCode'

         Code:
           ZipFile: !Sub |
            from __future__ import print_function
            import json
            import time
            import boto3
            from urllib.request import urlopen, Request
            transcribe = boto3.client('transcribe')
            sns = boto3.client('sns')
            import os

            def lambda_handler(event, context):
              if event:
                job_name = context.aws_request_id
                file_obj = event["Records"][0]
                bucket_name = str(file_obj['s3']['bucket']['name'])
                file_name = str(file_obj['s3']['object']['key'])
                s3_uri = create_uri(bucket_name, file_name)
                transcribe.start_transcription_job(
                  TranscriptionJobName=job_name,
                  Media={'MediaFileUri': s3_uri},
                  MediaFormat='wav',
                  LanguageCode= os.environ['LanguageCode']
                  )
              while True:
                status = transcribe.get_transcription_job(TranscriptionJobName=job_name)
                if status['TranscriptionJob']['TranscriptionJobStatus'] in ['COMPLETED', 'FAILED']:
                  break
                print("Not ready yet...")
                time.sleep(5)
                print(status)

              loadUrl = urlopen(status["TranscriptionJob"]["Transcript"]["TranscriptFileUri"])
              data = loadUrl.read()
              encoding = loadUrl.info().get_content_charset('utf-8')
              data = json.loads(data.decode(encoding))
              transcript_text = data['results']['transcripts'][0]['transcript']


              client = boto3.client('sns')
              response = client.publish(
                TargetArn=os.environ["SnsTopic"],
                Message=transcript_text
                )

            def create_uri(bucket_name, file_name):
              return "s3://"+bucket_name+"/"+file_name

    lambdaRoletoRunTranscribe:
      Type: 'AWS::IAM::Role'
      Properties:
        AssumeRolePolicyDocument:
          Version: 2012-10-17
          Statement:
          -
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
        Policies:
          - PolicyName: lambdarole
            PolicyDocument:
              Version: 2012-10-17
              Statement:
                - Effect: Allow
                  Action:
                    - 'transcribe:StartTranscriptionJob'
                    - 'transcribe:GetTranscriptionJob'
                    - 'transcribe:GetTranscriptionJob'
                  Resource: '*'

                - Effect: Allow
                  Action:
                    - 'sns:Publish'
                  Resource: !Ref 'SnsTopic'

                - Effect: Allow
                  Action:
                    - 's3:GetObject'
                  Resource:  { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "SourceS3Bucket" } , "/*" ]]}

                - Effect: Allow
                  Action:
                    - logs:CreateLogGroup
                    - logs:CreateLogStream
                    - logs:PutLogEvents
                  Resource: '*'



    LambdaInvokePermission:
      Type: AWS::Lambda::Permission
      Properties:
        FunctionName:
           Fn::GetAtt:
             - "LambdaTranscribe"
             - "Arn"
        Action: 'lambda:InvokeFunction'
        Principal: s3.amazonaws.com
        SourceAccount: !Ref 'AWS::AccountId'
        SourceArn:   { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "SourceS3Bucket" }]]}


    S3Bucket:
      Type: AWS::S3::Bucket
      DependsOn: LambdaInvokePermission
      Properties:
        BucketName:  !Ref 'SourceS3Bucket'
        AccessControl: Private
        NotificationConfiguration:
          LambdaConfigurations:
          - Event: 's3:ObjectCreated:*'
            Function: !GetAtt LambdaTranscribe.Arn

Outputs:
  BucketName:
    Value: !Ref 'S3Bucket'
    Description: Name of the sample Amazon S3 bucket to store the recording.

  lambdaRole:
    Value: !Ref 'lambdaRoletoRunTranscribe'

  RaspberryPiUserName:
    Value: !Ref 'raspberryPitoS3IAMUser'

  Lambda:
    Value: !Ref 'LambdaTranscribe'
